/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package nl.biggrid.plier.tools;

import java.util.Collection;
import java.util.Iterator;
import java.util.LinkedHashSet;

import javax.jdo.Extent;
import javax.jdo.PersistenceManager;
import javax.jdo.PersistenceManagerFactory;
import javax.jdo.JDOHelper;
import javax.jdo.Query;
import javax.jdo.Transaction;

import nl.biggrid.plier.event.Event;
import nl.biggrid.plier.opm.Account;
import nl.biggrid.plier.opm.Agent;
import nl.biggrid.plier.opm.Artifact;
import nl.biggrid.plier.opm.Dependency;
import nl.biggrid.plier.opm.OPMGraph;
import nl.biggrid.plier.opm.Process;
import nl.biggrid.plier.opm.Role;
import nl.biggrid.plier.opm.Used;
import nl.biggrid.plier.opm.WasGeneratedBy;
import nl.biggrid.plier.opm.WasControlledBy;

/**
 *
 * @author vguevara
 */
public class OPMPersistance {

    public static OPMGraph createOPM() {
        Account mainAccount = new Account();
        mainAccount.setId("main");
        mainAccount.setValue("main account");

        LinkedHashSet<Account> accountList = new LinkedHashSet<Account>();
        accountList.add(mainAccount);

        Agent agent1 = new Agent();
        agent1.setId("John");
        agent1.setValue("John Doe");
        agent1.addAccount(mainAccount);

        Agent agent2 = new Agent();
        agent2.setId("bakery");
        agent2.setValue("Fresh Bakery Amsterdam");
        agent2.addAccount(mainAccount);

        LinkedHashSet<Agent> agentList = new LinkedHashSet<Agent>();
        agentList.add(agent1);
        agentList.add(agent2);


        Process process = new Process();
        process.setId("baking cake with ingredients");
        process.setValue("Bake");
        process.addAccount(mainAccount);

        LinkedHashSet<Process> processList = new LinkedHashSet<Process>();
        processList.add(process);

        Artifact artifact1 = new Artifact();
        artifact1.setId("butter");
        artifact1.setValue("100g butter");
        artifact1.addAccount(mainAccount);

        Artifact artifact2 = new Artifact();
        artifact2.setId("eggs");
        artifact2.setValue("two eggs");
        artifact2.addAccount(mainAccount);

        Artifact artifact3 = new Artifact();
        artifact3.setId("flour");
        artifact3.setValue("100 g flour");
        artifact3.addAccount(mainAccount);

        Artifact artifact4 = new Artifact();
        artifact4.setId("suggar");
        artifact4.setValue("100 g suggar");
        artifact4.addAccount(mainAccount);

        Artifact artifact5 = new Artifact();
        artifact5.setId("cake");
        artifact5.setValue("cake");
        artifact5.addAccount(mainAccount);

        LinkedHashSet<Artifact> artifactList = new LinkedHashSet<Artifact>();
        artifactList.add(artifact1);
        artifactList.add(artifact2);
        artifactList.add(artifact3);
        artifactList.add(artifact4);
        artifactList.add(artifact5);

        Used u1 = new Used();
        u1.setEffect(artifact1.getId());
        u1.setCause(process.getId());
        u1.setRole("(butter)");

        Used u2 = new Used();
        u2.setEffect(artifact2.getId());
        u2.setCause(process.getId());
        u2.setRole("(egg)");

        Used u3 = new Used();
        u3.setEffect(artifact3.getId());
        u3.setCause(process.getId());
        u3.setRole("(flour)");

        Used u4 = new Used();
        u4.setEffect(artifact4.getId());
        u4.setCause(process.getId());
        u4.setRole("(sugar)");

        WasGeneratedBy WasGeneratedBy1 = new WasGeneratedBy();
        WasGeneratedBy1.setEffect(process.getId());
        WasGeneratedBy1.setCause(artifact5.getId());
        WasGeneratedBy1.setRole("(cake)");

        WasControlledBy WasControlledBy2 = new WasControlledBy();
        WasControlledBy2.setEffect(process.getId());
        WasControlledBy2.setCause(agent2.getId());
        WasControlledBy2.setRole("(bakery)");

        WasControlledBy WasControlledBy1 = new WasControlledBy();
        WasControlledBy1.setEffect(process.getId());
        WasControlledBy1.setCause(agent1.getId());
        WasControlledBy1.setRole("(baker)");

        LinkedHashSet<Dependency> causal = new LinkedHashSet<Dependency>();
        causal.add(u1);
        causal.add(u2);
        causal.add(u3);
        causal.add(u4);
        causal.add(WasControlledBy2);
        causal.add(WasGeneratedBy1);
        causal.add(WasControlledBy1);

        OPMGraph toReturn = new OPMGraph();
        toReturn.setId("Victoria_Sponge_Cake_Provenance");
        toReturn.setDescription("A Provenance graph expressing that John baked a cake with ingredients butter, eggs, sugar and flour");
        toReturn.setAccounts(accountList);
        toReturn.setAgents(agentList);
        toReturn.setArtifacts(artifactList);
        toReturn.setProcesses(processList);
        toReturn.setDependencies(causal);

        return toReturn;
    }


    public static void main(String args[])
    {
        // Dependencyeate a PersistenceManagerFactory for this datastore
        PersistenceManagerFactory pmf = JDOHelper.getPersistenceManagerFactory("datanucleus.properties");

        System.out.println("DataNucleus AccessPlatform with JDO");
        System.out.println("===================================");

        // Persistence of an OPMGraph.
        PersistenceManager pm = pmf.getPersistenceManager();
        Transaction tx=pm.currentTransaction();
        try
        {
            tx.begin();
            System.out.println("Persisting OPM graph");
            OPMGraph opmGraph = createOPM();
            //opmGraph.SetInverseRelations();
            pm.makePersistent(opmGraph);

            tx.commit();
            System.out.println("OPMGraph has been persisted");
        }
        finally
        {
            if (tx.isActive())
            {
                tx.rollback();
            }
            pm.close();
        }
        System.out.println("### END INSERTION ###");

        System.out.println("### NOW QUERYING ###");

        // Perform some query operations
        pm = pmf.getPersistenceManager();
        tx = pm.currentTransaction();
        try
        {
            tx.begin();
            System.out.println("### Executing Query for OPMGraphs ###");
            Extent e=pm.getExtent(OPMGraph.class,true);
            Query q=pm.newQuery(e, "");
            Collection c=(Collection)q.execute();
            Iterator iter=c.iterator();
            while (iter.hasNext())
            {
                Object obj = iter.next();
                //System.out.println(">  " + obj);
                // Give an example of an update
                if (obj instanceof OPMGraph)
                {
                    OPMGraph b = (OPMGraph)obj;
                    System.out.println("OPMGraph:  id=" + b.getId() + " desc=" + b.getDescription());
                }
            }
            tx.commit();
        }
        finally
        {
            if (tx.isActive())
            {
                tx.rollback();
            }
            pm.close();
        }
    }
}
